home *** CD-ROM | disk | FTP | other *** search
- /*========================================================*/
- /*-SOURCE OF (stest.c) ------------------------------*/
- /*--------------------------------------------------------*/
- /* (C) Jul/1998 Dr. Adil Temel (atemel@hotmail.com) */
- /*--------------------------------------------------------*/
- /* stest.c : BSD Socket test & RAW transfer speed */
- /* Created : 19980710 03:41:42 Fri */
- /* Last Modified: 19980712 19:06:52 Sun */
- /*========================================================*/
-
- #define VERSION "0.5"
- /*--------------------------------------------------------*/
- #define PORTNUM 50000 /* random port number, we need something */
- /*--------------------------------------------------------*/
- #define MAXDATA (2*1024*1024L) /* 1024K transfer */
- /*--------------------------------------------------------*/
- #define MAXBUF (1024L) /* Unit of transfer */
- /*--------------------------------------------------------*/
- #define DUMPLEN (0x40) /* dump last received/sent data */
- /*--------------------------------------------------------*/
- #include <errno.h>
- #include <signal.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <time.h>
-
- #include <unistd.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <sys/wait.h>
- #include <netinet/in.h>
- #include <netdb.h>
-
- /*--------------------------------------------------------*/
- #ifdef AMIGA
- /*--------------------------------------------------------*/
- #include <exec/types.h>
- /*--------------------------------------------------------*/
- #else
- typedef signed long LONG; /* signed 32-bit quantity */
- typedef unsigned long ULONG; /* unsigned 32-bit quantity */
- typedef signed short WORD; /* signed 16-bit quantity */
- typedef unsigned short UWORD; /* unsigned 16-bit quantity */
- typedef signed char BYTE; /* signed 8-bit quantity */
- typedef unsigned char UBYTE; /* unsigned 8-bit quantity */
- #endif
-
-
-
- #define COMPILENAME "SocketTest"
- /*--------------------------------------------------------*/
- #define PROGRAMNAME COMPILENAME " V" VERSION
- /*--------------------------------------------------------*/
- #define COPYRIGHT PROGRAMNAME" Test BSD socket communication.\n" \
- "Written by Dr. Adil Temel (E-Mail: atemel@hotmail.com) (C) 1998\r\n"
- /*--------------------------------------------------------*/
-
- #ifndef MAXHOSTNAME
- #define MAXHOSTNAME 256
- #endif
- #define RETSIGTYPE void
-
- /*--------------------------------------------------------*/
- long ntol(char *s);
- char sw_server=0,sw_quiet=0,sw_verbose=0,sw_random=0;
- char sw_debug=0,sw_checksum=0,sw_readback=0;
- char sw_keepalive=0;
-
- char *kw_hostname=NULL;
-
- /*--------------------------------------------------------*/
- unsigned short int portnum=PORTNUM;
- /*--------------------------------------------------------*/
- long maxbuf=MAXBUF,maxdata=MAXDATA;
- char *bufptr=NULL;
-
- /*--------------------------------------------------------*/
- #ifndef TRUE
- #define TRUE 1
- #define FALSE 0
- #endif
- /*--------------------------------------------------------*/
- RETSIGTYPE fireman(int x);
- int get_connection(int s);
- int establish(unsigned short portnum);
- int call_socket(char *hostname, unsigned short portnum);
- int mygethostname(char *hostname,int maxlen);
- struct hostent *mygethostent(char *hostname);
- /*--------------------------------------------------------*/
- int send_long(int s, long l);
- int send_word(int s, short l);
- int send_byte(int s, char l);
- /*--------------------------------------------------------*/
- int get_long(int s, long *l);
- int get_word(int s, short *l);
- int get_byte(int s, char *l);
- /*--------------------------------------------------------*/
- int read_data (int s,char *buf,int n);
- int write_data(int s,char *buf,int n);
- /*--------------------------------------------------------*/
- int receive_data(int s);
- int send_data(void);
-
- /*--------------------------------------------------------*/
- void CurrentTime(ULONG *s,ULONG *m);
- void DiffTime(ULONG *s1,ULONG *m1,ULONG s2,ULONG m2);
- char *SPrintTime(ULONG s,ULONG m);
- /*--------------------------------------------------------*/
- long memrnd(void *d,long sd,long len);
- void memcsum(void *d,ULONG *cs,long len);
- void memdump(void *s,long len,long adr);
- char *dumpadr(char *s,long len);
-
- unsigned long RangeSeed(unsigned long s);
- unsigned short int RangeRand(int d6);
- /*--------------------------------------------------------*/
- int main(int argc,char **argv)
- {
- int s, t;
- int i,x,ret;
- char *karg,skip,argused;
- printf(COPYRIGHT);
- //printf(COMPILEDATE);
- if(argc>=2)
- if(argv[1][0]=='?')
- {
- usage:
- printf("Usage: "COMPILENAME" [OPTIONS]\n");
- printf("Available options: (use with prefix - or /)\n");
- printf("----------------------------------------------\n");
- printf(" -s Run as server\n");
- printf(" -pPORTNUM Use this portnumber\n");
- printf(" -nHOSTNAME Call which computer\n");
- printf(" -bMAXBUF_K Buffer sizeK [1K]\n");
- printf(" -eMAXDATA_K Send data sizeK [1024K]\n");
- printf(" -r Use randomized data (hardly compressible)\n");
- printf(" -c Use simple checksum\n");
- printf(" -f Read back written data\n");
- printf(" -k Use socket option: SO_KEEPALIVE\n");
- printf(" -d DEBUG\n");
- exit(0);
- }
- for(i=1;i<argc;i++)
- if(argv[i][0]=='-' || argv[i][0]=='/')
- {
- karg=&argv[i][2];skip=0;argused=0;
- if(!*karg)
- {
- karg=argv[i+1];skip=1;
- if(!karg || *karg=='-' || *karg=='/') {karg="";skip=0;}
- }
- if(!karg) karg="";/* no NULL ptr */
- switch(argv[i][1]|0x20)
- {
- case 'h':
- case '?': goto usage;
- case 'p': portnum=ntol(karg);argused=1;
- if(!portnum) portnum=PORTNUM;
- break;
- case 'b': maxbuf=ntol(karg)*1024L;argused=1;
- if(maxbuf<=0 || maxbuf>(512*1024L)) maxbuf=MAXBUF;
- break;
- case 'e': maxdata=ntol(karg)*1024L;argused=1;
- if(maxdata<=0 || maxdata>(16384*1024L)) maxdata=MAXDATA;
- break;
- case 'n': kw_hostname=karg;argused=1;break;
- case 'k': sw_keepalive=TRUE;break;
- case 'c': sw_checksum=TRUE;break;
- case 'f': sw_readback=TRUE;break;
- case 'r': sw_random=TRUE;break;
- case 's': sw_server=TRUE;break;
- case 'd': sw_debug =TRUE;break;
- case 'v': sw_verbose=TRUE;sw_quiet=FALSE;break;
- case 'q': sw_verbose=FALSE;sw_quiet=TRUE;break;
- break;
- default: printf("Unknown option %s ignored\n",argv[i]);
- }
- if(argused) i+=skip;
- }
- bufptr=malloc(maxbuf);
- if(!bufptr)
- {
- fprintf(stderr,"Can't get %ld buffer.\n",maxbuf);
- exit(1);
- }
- printf("Using portnum %d , buf %ldK , data %ldK\n",(long) portnum,maxbuf>>10L,maxdata>>10L);
- if(!sw_server)
- {
- send_data();
- exit(0);
- }
- printf("Running as server..\n");
- if ((s= establish(portnum)) < 0) { /* plug in the phone */
- perror("establish");
- exit(1);
- }
- #if 0
- signal(SIGCHLD, fireman); /* this eliminates zombies */
- #endif
- printf("Waiting for connections.\n");
-
- for (;;) { /* loop for phone calls */
- if ((t= get_connection(s)) < 0) { /* get a connection */
- if (errno == EINTR) /* EINTR might happen on accept(), */
- continue; /* try again */
- perror("accept"); /* bad */
- exit(1);
- }
- #if 0 //#ifndef AMIGA
- switch(fork()) { /* try to handle connection */
- case -1 : /* bad news. scream and die */
- perror("fork");
- close(s);
- close(t);
- exit(1);
- case 0 : /* we're the child, do something */
- close(s);
- receive_data(t);
- exit(0);
- default : /* we're the parent so look for */
- close(t); /* another connection */
- continue;
- }
- #else
- receive_data(t);
- close(t);
- #endif
-
- }
- }
-
- /* as children die we should get catch their returns or else we get
- * zombies, A Bad Thing. fireman() catches falling children.
- */
- RETSIGTYPE fireman(int x)
- {
- //printf("fireman started.\n");
- while (waitpid(-1,NULL,WNOHANG) > 0) ;
- //printf("fireman finished.\n");
- }
-
-
- long bytes_msec(ULONG b,ULONG s,ULONG m)
- {
- m=m/1000L+s*1000L;if(!m) m=1;
- b/=m;
- return b;
- }
- /*--------------------------------------------------------*/
- void say_result(char *info,ULONG tot,ULONG totb, ULONG s1,ULONG m1,ULONG s2,ULONG m2)
- {
- ULONG b;
- char *rwmode;
- DiffTime(&s1,&m1,s2,m2);
- tot+=totb;b=bytes_msec(tot,s1,m1);
- if(totb)
- {
- rwmode= sw_server ? "READ/WRITE":"WRITE/READ";
- }
- else
- {
- rwmode= sw_server ? "WRITE":"READ";
- }
- printf("%s: total %ldK (%ld bytes) %s (%ld bytes/msec %ld bytes/sec %ldK/sec ).\n",
- info,
- tot/1024L,tot,rwmode,
- b,b*1000L,b*1000L/1024L);
- printf("%s: elapsed Time ticks: %s\n",info,SPrintTime(s1,m1));
- }
-
- /*--------------------------------------------------------*/
- #if 0
- /*
- After you create a socket to get calls, you must wait for calls to that
- socket. The accept() function is used to do this. Calling accept() is
- analogous to picking up the telephone if it's ringing. Accept() returns a
- new socket which is connected to the caller.
-
- The following function can be used to accept a connection on a socket that
- has been created using the establish() function above:
- */
-
- #endif
- /*--------------------------------------------------------*/
- #define PARMF_RAND (1L<<0)
- #define PARMF_CSUM (1L<<1)
- #define PARMF_RBACK (1L<<2)
- #define PARMF_PSIG (1L<<7) /* parameter id */
- /*--------------------------------------------------------*/
- #define START_BYTE (0xAC)
- /*--------------------------------------------------------*/
- int send_data(void)
- {
- int s,i,c;
- ULONG l;
- ULONG s1,s2,m1,m2;
- ULONG len,tot=0,totb=0,csum=0,rs=0;
- UBYTE x=0;
- char name[MAXHOSTNAME+1];
- UBYTE parm=PARMF_PSIG;
- if(sw_random ) parm|=PARMF_RAND;
- if(sw_checksum) parm|=PARMF_CSUM;
- if(sw_readback) parm|=PARMF_RBACK;
-
- if(kw_hostname) strcpy(name,kw_hostname);
- else mygethostname(name, MAXHOSTNAME); /* who are we? */
-
- printf("send_data: sending to %s port %d\n",name,(long)portnum);
- if( (s=call_socket(name,portnum)) <0)
- {
- fprintf(stderr,"cannot connect.\n");
- return -1;
- }
- len=maxdata;
- printf("send_data: socket %d , sending %ld\n",s,len);
- if(send_long(s,len)<0)
- {
- error:
- printf("send_data: failed to send parameter!\n");
- goto fin;
- }
- if(send_byte(s,parm)>=0)
- {
- if(parm& PARMF_RAND) printf("send_data: will send random data.\n");
- if(parm& PARMF_CSUM) printf("send_data: will use checksum.\n");
- if(parm& PARMF_RBACK) printf("send_data: will read back sent data\n");
- } else goto error;
- len=maxdata;
- if(len && len<maxbuf) l=len;else l=maxbuf;
- if(!len) len=MAXBUF;/* default send length */
- /* Dummy data */
- if(parm & PARMF_RAND)
- {
- rs=memrnd(bufptr,time(NULL),l);
- if(send_long(s,rs)<0) goto error;
- printf("send_data: using random seed 0x%08lx\n",rs);
- }
- else memset(bufptr,x++,l);
- if(send_byte(s,START_BYTE)<0) goto error;
- CurrentTime(&s1,&m1);
- while(len && (c=write_data(s,bufptr,l)) >0 )
- {
- #if 0
- if(sw_random) memrnd(bufptr,-1,l);
- else memset(bufptr,x++,l);
- #endif
- if(parm&PARMF_CSUM) memcsum(bufptr,&csum,l);
- if(parm&PARMF_RBACK)
- {
- if(read_data(s,bufptr,c)<c)
- {
- printf("send_data: cannot read %d\n",c);
- break;
- } else totb+=c;
- }
- tot+=c;len-=c;
- if(len<maxbuf) l=len;else l=maxbuf;
- }
- CurrentTime(&s2,&m2);
- memdump(bufptr+c-DUMPLEN,DUMPLEN,tot-DUMPLEN);
- say_result("send_data",tot,totb,s1,m1,s2,m2);
- if(parm&PARMF_CSUM)
- {
- printf("send_data: checksum 0x%08lx\n",csum);
- send_long(s,csum);
- }
- fin:
- close(s);
- printf("send_data: socket closed.\n");
- return 0;
- }
-
- /*--------------------------------------------------------*/
- /* this is the function that plays with the socket.it will*/
- /* be called after getting a connection. */
- /*--------------------------------------------------------*/
- int receive_data(int s)
- {
- int i,c;
- ULONG l;
- ULONG s1,s2,m1,m2;
- ULONG len,tot=0,totb=0,csum=0,rs=0;
- UBYTE parm=0;
- UBYTE start;
- printf("receive_data: socket %d\n",s);
- if(get_long(s,&len)<0)
- {
- error:
- printf("receive_data: failed to read parameter!\n");
- goto fin;
- }
- printf("receive_data: expecting %ld bytes\n",len);
- if(get_byte(s,&parm)>=0)
- {
- if(!(parm&PARMF_PSIG)) {printf("receive_data: wrong parameter received.\n");goto fin;}
- if(parm&PARMF_RAND) printf("receive_data: will receive random data.\n");
- if(parm&PARMF_CSUM) printf("receive_data: will use checksum.\n");
- if(parm&PARMF_RBACK) printf("receive_data: will write back received data\n");
- }
- else goto error;
-
- if(parm&PARMF_RAND)
- {
- if(get_long(s,&rs)<0) goto error;
- printf("receive_data: remote random seed 0x%08lx\n",rs);
- }
- if(len && len<maxbuf) l=len;else l=maxbuf;
- if(!len) len=0xFFFFFFFF;
- if(get_byte(s,&start)) goto error;
- if(start!=START_BYTE)
- {
- printf("receive_data: wrong start byte 0x%02lX (expecting 0x%02lX)\n",
- start,START_BYTE);
- goto error;
- }
- CurrentTime(&s1,&m1);
- while(len && (c=read_data(s,bufptr,l)) >0 )
- {
- if(parm&PARMF_CSUM) memcsum(bufptr,&csum,l);
- if(parm&PARMF_RBACK)
- {
- if(write_data(s,bufptr,c)<c)
- {
- printf("receive_data: cannot re-send received data %d\n",c);
- break;
- } else totb+=c;
- }
-
- tot+=c;len-=c;
- if(len<maxbuf) l=len;else l=maxbuf;
- }
- CurrentTime(&s2,&m2);
- memdump(bufptr+c-DUMPLEN,DUMPLEN,tot-DUMPLEN);
- say_result("receive_data",tot,totb,s1,m1,s2,m2);
- if(parm&PARMF_CSUM)
- {
- ULONG rsum;
- get_long(s,&rsum);
- printf("receive_data: checksum remote 0x%08lx%s0x%08lx %s\n",
- rsum,rsum==csum ? "==":"!=",csum, rsum==csum ? "OK!":"FAILURE!!");
- }
- fin:
- printf("receive_data: exit\n");
- return 0;
- }
- /*--------------------------------------------------------*/
- int ONE = 1;
- /*--------------------------------------------------------*/
- int sokeepalive(int s)
- {
- int r;
- printf("sokeepalive: keeping %d alive\n",s);
- r= setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, &ONE, sizeof ONE);
- printf("sokeepalive: setsockopt returned %d\n",r);
- return r;
- }
-
- /*--------------------------------------------------------*/
- /* send a long lvalue across network */
- /*--------------------------------------------------------*/
- int send_long(int s, long l)
- {
- l=htonl(l);/* host to network long */
- if(write_data(s,(char *)&l,sizeof(long))==sizeof(long)) return 0;
- return -1;/* Failed */
- }
- /*--------------------------------------------------------*/
- /* get a long lvalue from network */
- /*--------------------------------------------------------*/
- int get_long(int s, long *l)
- {
- long x;
- if(read_data(s,(char *)&x,sizeof(long))==sizeof(long))
- {
- *l=ntohl(x);/* network to host long */
- return 0;
- }
- return -1;/* failed */
- }
- /*--------------------------------------------------------*/
- /* send a word lvalue across network */
- /*--------------------------------------------------------*/
- int send_word(int s, short l)
- {
- l=htons(l);/* host to network long */
- if(write_data(s,(char *)&l,sizeof(long))==sizeof(long)) return 0;
- return -1;/* Failed */
- }
- /*--------------------------------------------------------*/
- /* get a word lvalue from network */
- /*--------------------------------------------------------*/
- int get_word(int s, short *l)
- {
- short x;
- if(read_data(s,(char *)&x,sizeof(short))==sizeof(short))
- {
- *l=ntohs(x);/* network to host long */
- return 0;
- }
- return -1;/* failed */
- }
-
- /*--------------------------------------------------------*/
- /* send a byte lvalue across network */
- /*--------------------------------------------------------*/
- int send_byte(int s, char l)
- {
- if(write_data(s,&l,sizeof(char))==sizeof(char)) return 0;
- return -1;/* Failed */
- }
- /*--------------------------------------------------------*/
- /* get a word lvalue from network */
- /*--------------------------------------------------------*/
- int get_byte(int s, char *l)
- {
- if(read_data(s,l,sizeof(char))==sizeof(char))
- {
- return 0;
- }
- return -1;/* failed */
- }
-
- /*--------------------------------------------------------*/
- /* Conversation (or: How to talk between sockets) */
- /* Now that you have a connection between sockets you want*/
- /* to send data between them. The read() and write() */
- /* functions are used to do this, just as they are for */
- /* normal files. There is only one major difference */
- /* between socket reading and writing and file reading */
- /* and writing: you don't usually get back the same number*/
- /* of characters that you asked for, so you must loop */
- /* until you have read the number of characters that you */
- /* want. A simple function to read a given number of */
- /* characters into a buffer is: */
- /*--------------------------------------------------------*/
- int read_data(int s,char *buf,int n)
- {
- int bcount=0; /* counts bytes read */
- int br=0; /* bytes read this pass */
- /* loop until full buffer */
- while(bcount<n)
- {
- if ((br= read(s,buf,n-bcount)) > 0)
- {
- bcount += br; /* increment byte counter */
- buf += br; /* move buffer ptr for next read */
- }
- else
- if(br<0) return(-1); /* signal an error to the caller */
- }
- return(bcount);
- }
- /*--------------------------------------------------------*/
- int write_data(int s,char *buf,int n)
- {
- int bcount=0; /* counts bytes read */
- int br=0; /* bytes read this pass */
- /* loop until full buffer */
- while(bcount<n)
- {
- if((br= write(s,buf,n-bcount)) > 0)
- {
- bcount += br; /* increment byte counter */
- buf += br; /* move buffer ptr for next read */
- }
- else
- if(br<0) return(-1); /* signal an error to the caller */
- }
- return(bcount);
- }
- /*--------------------------------------------------------*/
- /* Determine hostent according to given name or current */
- /* machine config */
- /*--------------------------------------------------------*/
- struct hostent *mygethostent(char *hostname)
- {
- struct hostent *hp;
- static struct hostent dm;
- static unsigned char bf[4];
- static char *ls[2],myname[MAXHOSTNAME+1];
- char *cx;
- if(!hostname || !*hostname)
- {
- mygethostname(myname,MAXHOSTNAME); /* who are we? */
- if(hostname) strcpy(hostname,myname);
- hostname=myname;
- }
- if(*hostname>='0' && *hostname<='9')
- {
- char *c=hostname;
- memset(bf,0,4);
- /* assume dot adress */
- bf[0]=atol(c);while(*c && *c!='.') c++;c++;
- bf[1]=atol(c);while(*c && *c!='.') c++;c++;
- bf[2]=atol(c);while(*c && *c!='.') c++;c++;
- bf[3]=atol(c);
- hp=&dm;
- memset(hp,0,sizeof(dm));
- hp->h_name=hostname;
- hp->h_aliases=NULL;
- hp->h_addrtype=2;
- hp->h_length=4;
- hp->h_addr_list=ls;
- ls[0]=bf;ls[1]=NULL;
- }
- else hp=gethostbyname(hostname);/* do we know the host's */
- return hp;/* return our static data */
- }
- /*--------------------------------------------------------*/
- /* Unlike with the telephone, you may still accept calls */
- /* while processing previous connections. For this reason */
- /* you usually fork off jobs to handle each connection. */
- /* The following code shows how to use establish() and */
- /* get_connection() to allow multiple connections to be */
- /* dealt with: */
- /*--------------------------------------------------------*/
- /* wait for a connection to occur on a socket created with*/
- /* establish() *
- /*--------------------------------------------------------*/
- int get_connection(int s)
- {
- int t; /* socket of connection */
- if ((t = accept(s,NULL,NULL)) < 0) /* accept connection if there is one */
- return(-1);
- if(sw_keepalive) sokeepalive(t);
- return(t);
- }
- /*--------------------------------------------------------*/
- /* Dialing (or: How to call a socket) */
- /* You now know how to create a socket that will accept */
- /* incoming calls. So how do you call it? As with the */
- /* telephone, you must first have the phone before using */
- /* it to call. You use the socket() function to do this, */
- /* exactly as you establish a socket to listen to. */
- /* After getting a socket to make the call with, and */
- /* giving it an address, you use the connect() function to*/
- /* try to connect to a listening socket. The */
- /* following function calls a particular port number on a */
- /* particular host: */
- /*--------------------------------------------------------*/
- /* This function returns a connected socket through which */
- /* data can flow. */
- /*--------------------------------------------------------*/
- int call_socket(char *hostname, unsigned short portnum)
- {
- struct sockaddr_in sa;
- struct hostent *hp;
- int a, s;
- if((hp= mygethostent(hostname)) == NULL) { /* do we know the host's */
- errno= ECONNREFUSED; /* address? */
- return(-1); /* no */
- }
- memset(&sa,0,sizeof(sa));
- memcpy((char *)&sa.sin_addr,hp->h_addr,hp->h_length); /* set address */
- sa.sin_family= hp->h_addrtype;
- sa.sin_port= htons((unsigned short)portnum);
-
- printf("call_socket: calling %s type=%ld %s:%ld\n",
- hostname,hp->h_addrtype,dumpadr(hp->h_addr,hp->h_length),(long)portnum);
-
- if ((s= socket(hp->h_addrtype,SOCK_STREAM,0)) < 0) /* get socket */
- return(-1);
- if(sw_keepalive) sokeepalive(s);
-
- if (connect(s,(struct sockaddr *)&sa,sizeof sa) < 0) { /* connect */
- close(s);
- return(-1);
- }
- return(s);
- }
- /*--------------------------------------------------------*/
- /* Establish a socket; originally from bzs@bu-cs.bu.edu */
- /*--------------------------------------------------------*/
- int establish(unsigned short portnum)
- {
- int s;
- struct sockaddr_in sa;
- struct hostent *hp;
- char *cx;
- static char myname[MAXHOSTNAME+1];
- myname[0]=0;
- if((hp= mygethostent(myname)) == NULL) { /* do we know the host's */
- errno= ECONNREFUSED; /* address? */
- return(-1); /* no */
- }
- printf("establish: %s adr type=%ld %s:%ld\n",
- myname,hp->h_addrtype,dumpadr(hp->h_addr,hp->h_length),(long)portnum);
- memset(&sa, 0, sizeof(struct sockaddr_in)); /* clear our address */
- sa.sin_family= hp->h_addrtype; /* this is our host address */
- sa.sin_port= htons(portnum); /* this is our port number */
- if ((s= socket(AF_INET, SOCK_STREAM, 0)) < 0) /* create socket */
- return(-1);
- if(sw_keepalive) sokeepalive(s);
-
- if (bind(s,(struct sockaddr *)&sa,sizeof(struct sockaddr_in)) < 0) {
- close(s);
- return(-1); /* bind address to socket */
- }
- listen(s, 3); /* max # of queued connects */
- return(s);
- }
- /*--------------------------------------------------------*/
- int mygethostname(char *hostname,int maxlen)
- {
- char *cx;
- gethostname(hostname,maxlen); /* who are we? */
- /* libsocket for djgpp kludge */
- if(*hostname)
- {
- cx=hostname+strlen(hostname)-1;
- while(cx>=hostname && *cx==' ') *cx--=0;
- }
- return *hostname ? 1:-1;
- }
- /*--------------------------------------------------------*/
- char *dumpadr(char *s,long len)
- {
- char *c;
- static char buf[500];
- long i;
- //printf("dumpadr: [%08lx] %ld\n",s,len);
- if(len>500-1) len=500-1;
- for(i=0,c=buf;i<len;i++)
- {
- sprintf(c,"%03ld.",(unsigned long) ((UBYTE)*s++) );c+=4;
- }
- *--c=0;/* remove last . */
- return buf;
- }
- /*--------------------------------------------------------*/
- void memdump(void *s,long len,long adr)
- {
- UBYTE *c=s;
- long i;
- for(i=0;i<len;i+=0x10,c+=0x10,adr+=0x10)
- printf("%08lX: %02lX%02lX%02lX%02lX %02lX%02lX%02lX%02lX %02lX%02lX%02lX%02lX %02lX%02lX%02lX%02lX\n",
- adr,
- c[0x0],c[0x1],c[0x2],c[0x3],
- c[0x4],c[0x5],c[0x6],c[0x7],
- c[0x8],c[0x9],c[0xa],c[0xb],
- c[0xc],c[0xd],c[0xe],c[0xf]);
- }
- /*--------------------------------------------------------*/
- /* return hexval+1 */
- /*--------------------------------------------------------*/
- UBYTE ishex(UBYTE c)
- {
- if((c>='0' && c<='9')) c=c-('0'-1);
- else
- {
- c|=0x20;/* lowercase */
- if(c>='a' && c<='f' ) c=c-('a'-10-1);
- else c=0;
- }
- return c;
- }
- /*--------------------------------------------------------*/
- long my_htol(char *s,char **ds)
- {
- register long l=0,sg;
- register UBYTE ch;
- if(*s=='-') {s++;sg=1;}else sg=0;
- /*----------------------------------*/
- /* Skip first chars if they are */
- /* '$' , '0x' or '0X' */
- /*----------------------------------*/
- if(*s=='$') s++;
- if(*s=='0' && (s[1]|0x20)=='x') s+=2;
- while((ch=ishex(*s))!=0)
- {
- l=(l<<4)+(ch-1);
- s++;
- }
- if(ds) *ds=s;/* Update ptr */
- return sg ? -l:l;
- }
- /*--------------------------------------------------------*/
- long ntol(char *s)
- {
- long num;
- if(*s=='0' && (s[1]|0x20)=='x') num=my_htol(s,NULL);
- else num=atol(s);
- return num;
- }
- /*--------------------------------------------------------*/
- char *htoa(long n,char ln)
- {
- register char *cx,c,h;
- static char buf[9];
- if(ln==0) ln=8;
- buf[ln]=0;cx=buf+ln-1;
- for(c=ln;c;c--,n>>=4,cx--)
- {
- h=n&0xF;
- if(h>=10) *cx=h+('A'-10);else *cx=h+'0';
- }
- return buf;
- }
- /*--------------------------------------------------------*/
- /*--------------------------------------------------------*/
- #define TIMEOFFSET ((((1978-1970)*365+2)*24+1)*60*60) // 252464400.00000 , 0xF0C4D10
- #define ADJUST (4*60*60)
-
- #if 1 //ifndef AMIGA
- void CurrentTime(ULONG *s,ULONG *m)
- {
- struct timeval tv;
- struct timezone tz;
- tz.tz_minuteswest=0;
- tz.tz_dsttime=0;
- gettimeofday(&tv,&tz);
- if(s) *s =(ULONG)tv.tv_sec-TIMEOFFSET+ADJUST;
- if(m) *m =(ULONG)tv.tv_usec;
- }
- #endif
-
- /* Calc *(m1)=m2-m1; */
- void DiffTime(ULONG *s1,ULONG *m1,ULONG s2,ULONG m2)
- {
- if(*m1>m2) {m2+=1000000L;s2--;}
- (*m1)=m2-*m1;
- (*s1)=s2-*s1;
- }
-
- char *SPrintTime(ULONG s,ULONG m)
- {
- static char buf[50];
- ULONG day,hour,min;
- day = s/(24*60*60L);s-=day*(24*60*60L);
- hour = s/(60*60L) ;s-=hour*(60*60L);
- min = s/60 ;s-=min*60;
- /* DD.HH:MM:SS.TT */
- sprintf(buf,"%02ld|%02ld:%02ld:%02ld.%06ld\n",
- day,hour,min,s,m);
- return buf;
- }
-
- long memrnd(void *d,long sd,long len)
- {
- UBYTE *p=d;
- if(sd!=-1) RangeSeed(sd);
- while(len--) *p++=RangeRand(256);
- return sd;
- }
-
- void memcsum(void *d,ULONG *cs,long len)
- {
- UBYTE *p=d;
- ULONG c=*cs;
- while(len--) c+=*p++;
- *cs=c;
- }
- /*--------------------------------------------------------*/
- static unsigned long seed=0;
- /*--------------------------------------------------------*/
- unsigned long RangeSeed(unsigned long s)
- {
- unsigned long o=seed;
- printf("RangeSeed: 0x%08lx\n",s);
- seed=s;
- return o;
- }
- /*--------------------------------------------------------*/
- unsigned short int RangeRand(int d6)
- {
- unsigned long d0,d1;
- unsigned short int d4,d5;
- d5=(unsigned short int)d6;
- d4=d5-1;d0=seed;
- do
- {
- d1=d0;d0+=d0;
- if(d0<=d1) d0^=0x1d872b41;
- d4>>=1;
- } while(d4);
- seed=d0;
- if(d5)
- {
- d0=d5*(d0&0xFFFF);
- return (unsigned short int)(d0>>16L);
- }
- return (unsigned short int)(d0&0xFFFF);
- }
-
-
-
- #if 0
- /*
-
- A very similar function should be used to write data; we leave that function
- as an exercise to the reader.
-
- Hanging Up (or: What to do when you're done with a socket)
-
- Just as you hang up when you're through speaking to someone over the
- telephone, so must you close a connection between sockets. The normal
- close() function is used to close each end of a socket connection. If one
- end of a socket is closed and the other tries to write to its end, the write
- will return an error.
-
- Speaking The Language (or: Byte order is important)
-
- Now that you can talk between machines, you have to be careful what you say.
- Many machines use differing dialects, such as ASCII versus (yech) EBCDIC.
- More commonly there are byte-order problems. Unless you always pass text,
- you'll run up against the byte-order problem. Luckily people have already
- figured out what to do about it.
-
- Once upon a time in the dark ages someone decided which byte order was
- "right". Now there exist functions that convert one to the other if
- necessary. Some of these functions are htons() (host to network short
- integer), ntohs() (network to host short integer), htonl() (host to network
- long integer), and ntohl() (network to host long integer). Before sending an
- integer through a socket, you should first massage it with the htonl()
- function:
-
- i= htonl(i);
- write_data(s, &i, sizeof(i));
-
- and after reading data you should convert it back with ntohl():
-
- read_data(s, &i, sizeof(i));
- i= ntohl(i);
-
- If you keep in the habit of using these functions you'll be less likely to
- goof it up in those circumstances where it is necessary.
-
- The Future Is In Your Hands (or: What to do now)
-
- Using just what's been discussed here, you should be able to build your own
- programs that communicate with sockets. As with all new things, however, it
- would be a good idea to look at what's already been done. While there are
- not a lot of books describing BSD sockets, one good reference is Unix
- Network Programming by W. Richard Stevens (Prentice-Hall 1990, ISBN
- 0-13-949876-1). In addition, you should look at some of the many
- public-domain applications which make use of sockets, since real
- applications are the best teachers. One such application is msend, a utility
- used to send messages between users on different hosts.
-
- Beware that the examples given here leave out a lot of error checking which
- should be used in a real application. You should check the manual pages for
- each of the functions discussed here for further information. If you have
- specific questions regarding sockets, please feel free to ask me at
- jimf@world.std.com.
- */
-
- #if 0
- printf("reading 256 ..\n");
- l=read_data(s,buf,256);
- printf("read %d bytes.\n",l);
- for(i=0,c=buf;i<l;i+=0x10,c+=0x10)
- printf("%02lX%02lX%02lX%02lX %02lX%02lX%02lX%02lX %02lX%02lX%02lX%02lX %02lX%02lX%02lX%02lX\n",
- c[0x0],c[0x1],c[0x2],c[0x3],
- c[0x4],c[0x5],c[0x6],c[0x7],
- c[0x8],c[0x9],c[0xa],c[0xb],
- c[0xc],c[0xd],c[0xe],c[0xf]);
- printf("receive_data: closing socket.\n");
- close(s);
- printf("done.. returning.\n");
- #endif
- #endif
-
- /*========================================================*/
- /*-END OF SOURCE (stest.c) --------------------------*/
- /*========================================================*/
-
-